#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define PRE_MAX (0xff)
#define ERRMSG_MAX (1024)

char errmsg[ERRMSG_MAX];

int error(int status);

/*
Usage:
mkpat -a CHAR -b CHAR -n REPEAT -r REPEAT -o FILE_NAME -p PREFIX -s SUFFIX
*/

int main(int argc, char *argv[])
{
    int i, j;
    char data[2];
    long repeat;
    char *end_addr;
    char *prefix;
    char *suffix;
    FILE *fptr;

    int which;

    prefix = suffix = 0;
    data[0] = '0';
    data[1] = '1';
    repeat = 10;
    fptr = 0;

    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-') /* option */
        {
            switch (argv[i][1])
            {
            case 'a':
                if (argv[i+1] == 0 || argv[i+1][0] == '-')
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a value.", i, argv[i]);
                    error(-1);
                }
                data[0] = argv[i+1][0];
                i++;

                break;

            case 'b':
                if (argv[i+1] == 0 || argv[i+1][0] == '-')
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a value.", i, argv[i]);
                    error(-1);
                }
                data[1] = argv[i+1][0];
                i++;

                break;

            case 'n':
                if (argv[i+1] == 0 || !isxdigit(argv[i+1][0]))
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a numeric value.", i, argv[i]);
                    error(-1);
                }
                repeat = strtol(argv[i+1], &end_addr, 0);
                if (end_addr == argv[i+1])
                {
                    sprintf(errmsg, "arg[%d] (%s): invalid number.", i+1, argv[i+1]);
                    error(-1);
                }
                i++;

                break;

            case 'p':
                if (argv[i+1] == 0 || argv[i+1][0] == '-')
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a value.", i, argv[i]);
                    error(-1);
                }
                prefix = argv[i+1];
                i++;
                break;

            case 's':
                if (argv[i+1] == 0 || argv[i+1][0] == '-')
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a value.", i, argv[i]);
                    error(-1);
                }
                suffix = argv[i+1];
                i++;
                break;

            case 'o': /* alpha 'Oh' */
                fptr = fopen(argv[i+1], "w");
                if (argv[i+1] == 0 || argv[i+1][0] == '-')
                {
                    sprintf(errmsg, "arg[%d] (%s): must give a value.", i, argv[i]);
                    error(-1);
                }
                if (fptr == 0)
                {
                    sprintf(errmsg, "Oops, cannnot open file \"%s\" to output.", argv[i+1]);
                    error(-1);
                }
                i++;
                break;

            default:
                sprintf(errmsg, "arg[%d] (%s): unknown option.", i, argv[i]);
                error(0);
                break;
            } /* switch (-?) */
        }
        else
        {
            sprintf(errmsg, "arg[%d] (%s): unknown option.", i, argv[i]);
            error(0);
        } /* if ('-') */
    } /* for (i = 1; i < argc; i++) */

    /* starting output */
    if (fptr == 0)
        fptr = stdout;

    for (i = 0; i < repeat; i++)
    {
        /****  First Line ****/

        /* prefix of the line*/
        prefix ? fprintf(fptr, "%s", prefix) : 0;

        which = 0; /* start from data[0] for first line */
        for (j = 0; j < 16; j++)
        {
            fprintf(fptr, "%c", data[which]);
            which = !which;
            if (j == 7) /* insert a space */
                fprintf(fptr, " ");
        }

        /* suffix of the line*/
        suffix ? fprintf(fptr, "%s", suffix) : 0;

        /* ending of one line*/
        fprintf(fptr, "\n");

        /****  Second Line ****/

        /* prefix of the line*/
        prefix ? fprintf(fptr, "%s", prefix) : 0;

        which = 1;
        for (j = 0; j < 16; j++)
        {
            fprintf(fptr, "%c", data[which]);
            which = !which;
            if (j == 7) /* insert a space */
                fprintf(fptr, " ");
        }

        /* suffix of the line*/
        suffix ? fprintf(fptr, "%s", suffix) : 0;

        /* ends of one repeat */
        fprintf(fptr, "\n");
    } /* for (all repeats) */

    return 0;
} /* main */

/*
    LST1 10691    /T3    ! 01 1 1 0 01010101 01010101
    LEN1        /T3    ! 01 1 1 0 10101010 10101010

  NOP        /T13    ! 01 1 0 1 XXXXXXXX XXXXXXXX

*/

int error(int status)
{
    if (status)
    {
        fprintf(stderr, "error: %s\n", errmsg);
        exit(status);
    }
    else
    {
        fprintf(stderr, "warning: %s\n", errmsg);
    }
    return 0;
}

